# -*- coding: utf-8 -*-
# 1.加载股票数据，并将其翻转以确保时间顺序的正确性
import numpy as np
import torch
torch.manual_seed(42)
data = np.loadtxt('data-02-stock_daily.csv', delimiter=',')
data = data[::-1]
# 2.创建一个新的列表y_binary，用于存储根据收盘价和开盘价的比较结果生成的二进制标签
# 3.如果收盘价大于开盘价，则标签为1，否则为0
y_binary = (data[:, -1] > data[:, 0]).astype(int)
print(y_binary)
# 4.使用MinMaxScaler对数据进行归一化处理
from sklearn.preprocessing import MinMaxScaler

data = MinMaxScaler().fit_transform(data)
# 5.设置时间窗口大小
c = 7
# 6.初始化输入特征列表
x = []
# 7.初始化目标变量列表
y = []
# 8.通过滑动窗口的方式生成训练数据集
for i in range(len(data) - c):
    # 9.获取当前时间窗口的数据作为输入特征
    x.append(data[i:i + c])
    # 10.获取对应的目标变量（二进制标签）
    y.append(data[i + c, -1])
# 11.将数据转换为torch张量，以便进行深度学习训练
x = torch.tensor(x, dtype=torch.float)
y = torch.tensor(y, dtype=torch.float).reshape(-1, 1)
# 12.划分训练集和测试集
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, shuffle=False, random_state=42)
# 13.打印训练集输入的形状，以便进行验证
print(x_train.shape, y_train.shape)
# 14.构建深度学习模型，包含一个线性层和一个Sigmoid激活函数
model = torch.nn.Sequential(
    torch.nn.Linear(in_features=5*7, out_features=1),
    torch.nn.Sigmoid()
)
# 15.使用二进制交叉熵损失函数和优化器
loss_fn = torch.nn.BCELoss()
optim_adam = torch.optim.Adam(model.parameters())
# 16.训练模型
model.train()
for i in range(2000):
    optim_adam.zero_grad()
    h = model(x_train.reshape(-1, 5*7))
    loss = loss_fn(h, y_train)
    loss.backward()
    optim_adam.step()
    if i % 100 == 0:
        print(i + 1, loss.item())
# 17.使用训练好的模型进行预测
model.eval()
with torch.no_grad():
    h = model(x_test.reshape(-1, 5*7))
    # 18.将预测结果转换为二进制标签
    predict = (h > 0.5).int()
    print(predict)
    # 19.计算并打印准确率
    acc = (predict == y_test).float().mean()
    print(acc)
